﻿// Inner Fire 游戏引擎库
// Lua绑定适配项目
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 所属层级：应用层(4)
// 用于Animator的Lua绑定适配。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-04-30

#include "game/animation/animation.h"
#include "game/animation/animator.h"
#include "lua_manager.h"
#include <game/object/instanced_sprite_object.h>

namespace ifire::game {

static int Animation_GetClip(lua_State* L) {
  auto ptr = L_THIS(Animation);
  const char* name = L_STR(2);
  return ikit::lua_return_object(L, ptr->FindClip(name), "AnimationClipMeta");
}

static int Animation_First(lua_State* L) {
  auto ptr = L_THIS(Animation);
  return ikit::lua_return_object(L, ptr->First(), "AnimationClipMeta");
}

static int Animator_Print(lua_State* L) {
  auto ptr = L_THIS(Animator);
  const char* name = L_STR(2);
  ptr->Print(name);
  return 0;
}

static int Animator_Play(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto clip = ikit::lua_get_userdata<AnimationClip>(L, 2, "AnimationClipMeta");
  bool is_loop = lua_toboolean(L, 3); // 是否循环
  auto loop = is_loop ? PlayMethod::Loop : PlayMethod::None;
  float transition = L_FLOAT(4);
  ptr->Play(clip, loop, transition);
  return 0;
}

static int Animator_PlayBlend(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto blend =
      ikit::lua_get_userdata<AnimationBlend>(L, 2, "AnimationBlendMeta");
  bool is_loop = lua_toboolean(L, 3); // 是否循环
  auto loop = is_loop ? PlayMethod::Loop : PlayMethod::None;
  float transition = L_FLOAT(4);
  ptr->PlayBlend(blend, loop, transition);
  return 0;
}

static int Animator_PlayPose(lua_State* L) {
  auto ptr = L_THIS(Animator);
  ptr->PlayPose();
  return 0;
}

static int Animator_PlayAvatar(lua_State* L) {
  auto ptr = L_THIS(Animator);
  ptr->PlayAvatar();
  return 0;
}

static int Animator_PlayRaw(lua_State* L) {
  auto ptr = L_THIS(Animator);
  ptr->PlayRaw();
  return 0;
}

static int Animator_PlayFrame(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto clip = L_OBJ(2, AnimationClip);
  lua_Number frame = lua_tonumber(L, 3);
  ptr->PlayFrame(clip, static_cast<float>(frame));
  return 0;
}

static int Animator_UseRootMotion(lua_State* L) {
  auto ptr = L_THIS(Animator);
  bool enable = lua_toboolean(L, 2);
  ptr->UseRootMotion(enable);
  return 0;
}

static int Animator_IsRootMotion(lua_State* L) {
  auto ptr = L_THIS(Animator);
  lua_pushboolean(L, ptr->IsRootMotion() ? 1 : 0);
  return 1;
}

static int Animator_GetRootMotionDelta(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto delta = ptr->GetRootMotionDelta();
  lua_pushnumber(L, (lua_Number)delta.x);
  lua_pushnumber(L, (lua_Number)delta.y);
  lua_pushnumber(L, (lua_Number)delta.z);
  return 3;
}

static int Animator_SetValue(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto delta = ptr->GetRootMotionDelta();
  float x = (float)lua_tonumber(L, 2);
  float y = 0.0f;
  int arg_count = lua_gettop(L); // 获取参数总数
  // 检查pid（索引2）是否存在且非nil
  if (arg_count >= 3 && !lua_isnil(L, 3)) {
    y = (float)lua_tonumber(L, 3);
  }
  ptr->SetValue(x, y);
  return 0;
}

static int Animator_SetSpriteInformation(lua_State* L) {
  auto ptr = L_THIS(Animator);
  const char* type = L_STR(2);
  auto obj = L_OBJ(3, InstancedSpriteObject);
  ptr->SetSpriteInformation(type, obj);
  return 0;
}

static int Animator_PopEvent(lua_State* L) {
  auto ptr = L_THIS(Animator);
  auto obj = ptr->GetEvents()->PopEvent();
  return ikit::lua_return_object(L, obj, "AnimatorEventMeta");
}

static int AnimationClip_Print(lua_State* L) {
  auto ptr = L_THIS(AnimationClip);
  ptr->Print();
  return 0;
}

static int AnimationClip_GetFps(lua_State* L) {
  auto ptr = L_THIS(AnimationClip);
  lua_pushnumber(L, (lua_Number)ptr->GetFps());
  return 1;
}

static int AnimationClip_GetDuration(lua_State* L) {
  auto ptr = L_THIS(AnimationClip);
  lua_pushnumber(L, (lua_Number)ptr->GetDuration());
  return 1;
}

static int AnimationBlend_Print(lua_State* L) {
  auto ptr = L_THIS(AnimationBlend);
  KLOG("AnimationBlend: %s", ptr->name.log_str());
  return 0;
}

static int AnimatorEvent_SetProcessed(lua_State* L) {
  auto ptr = L_THIS(AnimatorEvent);
  ptr->SetProcessed();
  return 0;
}
static int AnimatorEvent_GetName(lua_State* L) {
  auto ptr = L_THIS(AnimatorEvent);
  lua_pushstring(L, ptr->GetName().c_str());
  return 1;
}

void register_lua_animator(lua_State* L, LuaManager* lua_manager) {
  // 注册Animator动画机的元表
  luaL_Reg animator_methods[] = {                              //
      {"Print", Animator_Print},                               //
      {"Play", Animator_Play},                                 //
      {"PlayBlend", Animator_PlayBlend},                       //
      {"PlayPose", Animator_PlayPose},                         //
      {"PlayAvatar", Animator_PlayAvatar},                     //
      {"PlayRaw", Animator_PlayRaw},                           //
      {"PlayFrame", Animator_PlayFrame},                       //
      {"UseRootMotion", Animator_UseRootMotion},               //
      {"IsRootMotion", Animator_IsRootMotion},                 //
      {"GetRootMotionDelta", Animator_GetRootMotionDelta},     //
      {"SetValue", Animator_SetValue},                         //
      {"SetSpriteInformation", Animator_SetSpriteInformation}, //
      {"PopEvent", Animator_PopEvent},                         //
      {NULL, NULL}};
  ikit::lua_register_metatable(L, "AnimatorMeta", animator_methods);

  // 注册Animation的元表
  luaL_Reg animation_methods[] = {    //
      {"GetClip", Animation_GetClip}, //
      {"First", Animation_First},     //
      {NULL, NULL}};
  ikit::lua_register_metatable(L, "AnimationMeta", animation_methods);

  // 注册AnimationClip的元表
  luaL_Reg animation_clip_methods[] = {           //
      {"Print", AnimationClip_Print},             //
      {"GetFps", AnimationClip_GetFps},           //
      {"GetDuration", AnimationClip_GetDuration}, //
      {NULL, NULL}};
  ikit::lua_register_metatable(L, "AnimationClipMeta", animation_clip_methods);

  // 注册AnimationBlend的元表
  luaL_Reg animation_blend_methods[] = {//
      {"Print", AnimationBlend_Print},  //
      {NULL, NULL}};
  ikit::lua_register_metatable(
      L, "AnimationBlendMeta", animation_blend_methods);

  // 注册AnimatorEvent的元表
  luaL_Reg animator_event_methods[] = {                  //
      {"SetProcessed", AnimatorEvent_SetProcessed}, //
      {"GetName", AnimatorEvent_GetName},           //
      {NULL, NULL}};
  ikit::lua_register_metatable(L, "AnimatorEventMeta", animator_event_methods);
}

} // namespace ifire::game